/**
 * Copyright (C) 2008 Christopher Allen Ogden
 *
 *     This file is part of Odysi.
 *
 *  Odysi is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  Odysi is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with Odysi.  If not, see <http://www.gnu.org/licenses/>.
 */
#pragma once

#include <map>
#include <string>

#define SOCKET_ERROR -1

typedef std::map<int, int> SocketList;

/**
 * Stores a socket.
 *
 * @author  Ogden, Chris
 */
class Socket {
    public:
        /**
         * Constructor.
         *
         * @param socket    The socket to set to.
         */
        Socket(int socket);

        /**
         * Destructor.
         */
        ~Socket();

        /**
         * Assignment operator.
         *
         * @param rhs   The socket being assigned to this.
         */
        Socket & operator=(const Socket &rhs);

        /**
         * Integer operator (const).
         */
        operator int(void) const;

        /**
         * Copy constructor.
         *
         * @param rhs   The Socket being copied.
         */
        Socket(const Socket &rhs);

        /**
         * Default constructor.
         */
        Socket();

        void setReuseAddress(void);

        void setNonblocking(void);

        void bind(int port);

        int accept(void);

        void listen(int queue);

        void connect(std::string host, int port);

        int send(const void * const data, int length);

        int recv(void * data, int length);

    private:
        void throwError(std::string message);

        /**
         * Set and increment the socket.
         *
         * @param socket    The socket to set to and increment.
         */
        void inc(int socket);

        /**
         * Decrement and close (if needed) the socket.
         */
        void dec(void);

        int _socket;
        static SocketList _list;
};

